package com.example.docking.controller;

import com.alibaba.fastjson.JSON;
import com.example.docking.dao.jindie.ResponseData;
import com.example.docking.dao.jindie.request.CommonOperateDao;
import com.example.docking.dao.jindie.request.MaterialEntity;
import com.example.docking.dao.jindie.request.SaveInvPickRequest;
import com.example.docking.dao.jindie.response.MoTaskbillDetailData;
import com.example.docking.dao.jindie.response.OrderList;
import com.example.docking.dao.jindie.response.PurInboundDetail;
import com.example.docking.dao.jindie.response.SaveData;
import com.example.docking.dao.jindie.response.motaskbill.SubMaterialEntity;
import com.example.docking.service.impl.DataServiceImpl;
import com.example.docking.util.Constants;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.smecloud.apigw.model.ApiResult;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;

import java.lang.reflect.Type;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * ERP采购入库单
 *
 * @author: tengguodong
 * @date: 2025/8/11
 */
@Slf4j
@Controller
public class ERPPurInboundController {
    private final Gson gson = new Gson();

    @SneakyThrows
    public void selectPurInbound() {
        log.info("ERP采购入库单");
        // 1.查询ERP采购入库单列表
        PurInboundController purInboundController = new PurInboundController();
        List<OrderList> orderLists = purInboundController.selectOrderList();
        for (OrderList orderList : orderLists) {
            // 2.查询ERP采购入库单详情
            PurInboundDetail purInboundDetail = selectPurInboundDetail(orderList.getId());
            // 3.生成生产领料单
            Map<String, MoTaskbillDetailData> moTaskbillDetailDataMap = new HashMap<>();
            SaveInvPickRequest saveInvPickRequest = new SaveInvPickRequest();
            // 使用LocalDate格式化当前日期
            LocalDate currentDate = LocalDate.now();
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            saveInvPickRequest.setBill_date(currentDate.format(formatter));
            List<MaterialEntity> material_entity =
                    purInboundDetail.getMaterial_entity().stream().map(
                            materialEntity -> {
                                MaterialEntity newMaterialEntity = new MaterialEntity();
                                newMaterialEntity.setMaterial_id(materialEntity.getMaterial_id());
                                newMaterialEntity.setQty(materialEntity.getQty());
                                newMaterialEntity.setStock_id(materialEntity.getStock_id());
                                newMaterialEntity.setSp_id(materialEntity.getSp_id());
                                newMaterialEntity.setUnit_id(materialEntity.getUnit_id());

                                // 查询生产任务单详情
                                MoTaskbillDetailData moTaskbillDetailData = selectMoTaskbillDetailData(materialEntity.getComment(), moTaskbillDetailDataMap);
                                List<com.example.docking.dao.jindie.response.MaterialEntity> moTaskbillDetailDataMaterialEntityList = moTaskbillDetailData.getMaterial_entity();
                                com.example.docking.dao.jindie.response.MaterialEntity moTaskmaterialEntity = moTaskbillDetailDataMaterialEntityList.get(0);
                                newMaterialEntity.setSrc_product_entry_id(moTaskmaterialEntity.getId());
                                List<SubMaterialEntity> subMaterialEntityList = moTaskmaterialEntity.getSub_material_entity();
                                Map<String, SubMaterialEntity> subMaterialEntityMap = subMaterialEntityList.stream().collect(Collectors.toMap(SubMaterialEntity::getSub_material_id,
                                        subMaterialEntity -> subMaterialEntity, (existing, newValue) -> existing));
                                SubMaterialEntity subMaterialEntity = subMaterialEntityMap.get(materialEntity.getMaterial_id());
                                newMaterialEntity.setSrc_entry_id(subMaterialEntity.getId());

                                newMaterialEntity.setSrc_bill_type_id("mo_task_bill");
                                newMaterialEntity.setSrc_inter_id(moTaskbillDetailData.getId());
                                return newMaterialEntity;
                            }
                    ).collect(Collectors.toList());
            saveInvPickRequest.setMaterial_entity(material_entity);
            DataServiceImpl service = new DataServiceImpl();
            ApiResult insertResult = service.InsertDataOne(Constants.INV_PICK, new HashMap<>(), saveInvPickRequest);
            log.info("生产领料单推送ERP结果：{}", JSON.toJSONString(insertResult));
            // 4.生产领料单审核
            auditInvPick(insertResult, service);
        }
    }

    private void auditInvPick(ApiResult insertResult, DataServiceImpl service) {
        ResponseData<SaveData> response = gson.fromJson(insertResult.getBody(), new TypeToken<ResponseData<SaveData>>() {
        }.getType());
        if (response.getErrcode() == 0) {
            log.info("生产领料单推送ERP成功");
            List<String> ids = response.getData().getIds();
            CommonOperateDao commonOperateDao = new CommonOperateDao();
            commonOperateDao.setEntity_number(Constants.INV_PICK_BILL);
            commonOperateDao.setIds(ids);
            commonOperateDao.setOperate_type(Constants.AUDIT);
            try {
                ApiResult auditData = service.SelectDataAudit(Constants.COMMON_OPERATE, new HashMap<>(), commonOperateDao);
                ResponseData<SaveData> auditResponse = gson.fromJson(auditData.getBody(), new TypeToken<ResponseData<SaveData>>() {
                }.getType());
                if (auditResponse.getErrcode() == 0) {
                    log.info("审核生产领料单成功, auditResponse = {}", auditResponse);
                } else {
                    log.error("审核生产领料单失败. auditResponse: {}", auditResponse);
                    throw new RuntimeException(auditResponse.getErrcode() + ":" + auditResponse.getDescription());
                }
            } catch (Exception e) {
                log.error("Error occurred while auditing sales order", e);
                throw new RuntimeException(e);
            }
        }
    }

    /**
     * 查询ERP采购入库单详情
     *
     * @param id
     * @return
     */
    @SneakyThrows
    public PurInboundDetail selectPurInboundDetail(String id) {
        log.info("ERP采购入库单详情");
        DataServiceImpl service = new DataServiceImpl();
        Gson gson = new Gson();
        HashMap<String, String> map = new HashMap<>();
        map.put("id", id);
        ApiResult result = service.SelectDataDetail(Constants.PUR_INBOUND_DETAIL, map, "");
        ResponseData<PurInboundDetail> response = gson.fromJson(result.getBody(), new TypeToken<ResponseData<PurInboundDetail>>() {
        }.getType());
        return response.getData();
    }

    private MoTaskbillDetailData selectMoTaskbillDetailData(String bill_no, Map<String, MoTaskbillDetailData> moTaskbillDetailDataMap) {
        log.info("根据编号获取生产任务单");
        if (moTaskbillDetailDataMap.containsKey(bill_no)) {
            return moTaskbillDetailDataMap.get(bill_no);
        }

        HashMap<String, String> map = new HashMap<>();
        map.put("number", bill_no);
        DataServiceImpl Service = new DataServiceImpl();
        Gson gson = new Gson();
        ApiResult DataResult = null;
        MoTaskbillDetailData genericDataItem = null;

        if (bill_no == null || bill_no.equals("")) {
            return genericDataItem;
        }

        try {
            DataResult = Service.SelectDataList(Constants.MO_TASKBILL_DETAIL, map, "");
            Type SaleDataType = new TypeToken<ResponseData<MoTaskbillDetailData>>() {
            }.getType();
            ResponseData<MoTaskbillDetailData> responseSaleData = gson.fromJson(DataResult.getBody(), SaleDataType);
            genericDataItem = responseSaleData.getData();
            log.info("code" + responseSaleData.getErrcode());
            log.info("描述" + responseSaleData.getDescription());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        moTaskbillDetailDataMap.put(bill_no, genericDataItem);
        return genericDataItem;
    }

    public static void main(String[] args) {
        ERPPurInboundController erpPurInboundController = new ERPPurInboundController();
        erpPurInboundController.selectPurInbound();
    }
}